import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# --- 步骤 1: 定义文件路径和工作表名称 ---
file_path = 'data.xlsx'
sheet_name = '男胎检测数据'

# --- 步骤 2: 读取数据 ---
try:
    df = pd.read_excel(file_path, sheet_name=sheet_name)
    print("成功读取Excel文件！")
    print(f"原始数据共有 {df.shape[0]} 行。")
except Exception as e:
    print(f"读取文件时发生错误: {e}")
    df = pd.DataFrame()

# --- 步骤 3: 数据预处理与特征工程 (在一个独立的逻辑块中完成) ---
if not df.empty:
    print("\n--- 开始进行数据预处理与特征工程 ---")

    def convert_to_weeks_robust(value):
        """
        一个更稳健的函数，可以处理字符串和数字。
        """
        # 如果值本身就是数字，直接返回
        if isinstance(value, (int, float)):
            return float(value) if pd.notna(value) else None

        # 如果不是字符串，无法处理
        if not isinstance(value, str):
            return None
        
        try:
            s = value.lower().strip() # 统一转为小写并去除空格
            if 'w+' in s:
                parts = s.split('w+')
                weeks = int(parts[0])
                days = int(parts[1])
                return float(weeks) + float(days) / 7.0
            elif 'w' in s:
                parts = s.split('w')
                weeks = int(parts[0])
                return float(weeks)
            else:
                # 尝试将纯数字字符串转为浮点数
                return float(s)
        except (ValueError, IndexError):
            return None

    # 应用新的转换函数
    df['孕周_连续'] = df['检测孕周'].apply(convert_to_weeks_robust)
    
    # 定义核心特征并进行数据清洗
    core_features = ['Y染色体浓度', '孕周_连续', '孕妇BMI']
    df.dropna(subset=core_features, inplace=True)
    
    print(f"预处理完成，用于分析的数据量: {df.shape[0]} 行。")


# --- 步骤 4: 可视化分析 (在预处理完成后，进行一次检查) ---
# 检查处理后的 df 是否还有数据
if 'df' in locals() and not df.empty:
    print("\n--- 开始进行可视化分析 ---")
    
    # 设置matplotlib正常显示中文和负号
    plt.rcParams['font.sans-serif'] = ['Heiti SC']
    plt.rcParams['axes.unicode_minus'] = False

    # 关键变量分布可视化
    plt.figure(figsize=(20, 6))
    plt.suptitle('关键变量数据分布图', fontsize=18)
    plt.subplot(1, 3, 1)
    sns.histplot(df['孕妇BMI'], kde=True, bins=40)
    plt.title('孕妇 BMI 分布', fontsize=14)
    plt.axvline(x=40, color='red', linestyle='--', label='BMI=40')
    plt.legend()
    
    plt.subplot(1, 3, 2)
    sns.histplot(df['孕周_连续'], kde=True, bins=40)
    plt.title('孕周 (连续周数) 分布', fontsize=14)

    plt.subplot(1, 3, 3)
    sns.histplot(df['Y染色体浓度'], kde=True, bins=40)
    plt.title('Y染色体浓度 (%) 分布', fontsize=14)
    plt.tight_layout(rect=[0, 0, 1, 0.95])
    plt.show()

    # 相关性可视化
    plt.figure(figsize=(18, 7))
    plt.suptitle('Y染色体浓度与关键指标的相关性散点图', fontsize=18)
    plt.subplot(1, 2, 1)
    sns.regplot(x='孕妇BMI', y='Y染色体浓度', data=df,
                scatter_kws={'alpha': 0.2, 's': 15}, line_kws={'color':'red'})
    plt.title('Y染色体浓度 vs. 孕妇 BMI', fontsize=14)
    plt.xlabel('孕妇 BMI 指标')
    plt.ylabel('Y染色体浓度 (%)')

    plt.subplot(1, 2, 2)
    sns.regplot(x='孕周_连续', y='Y染色体浓度', data=df,
                scatter_kws={'alpha': 0.2, 's': 15}, line_kws={'color':'red'})
    plt.title('Y染色体浓度 vs. 孕周', fontsize=14)
    plt.xlabel('孕周 (连续周数)')
    plt.ylabel('Y染色体浓度 (%)')
    plt.tight_layout(rect=[0, 0, 1, 0.95])
    plt.show()

    # 分组差异可视化
    bins = [0, 20, 28, 32, 36, 40, df['孕妇BMI'].max()+1]
    labels = ['<20', '[20,28)', '[28,32)', '[32,36)', '[36,40)', '>=40']
    df['BMI_分组'] = pd.cut(df['孕妇BMI'], bins=bins, labels=labels, right=False)
    plt.figure(figsize=(12, 8))
    sns.boxplot(x='BMI_分组', y='Y染色体浓度', data=df)
    plt.title('不同BMI分组下的Y染色体浓度分布', fontsize=16)
    plt.xlabel('BMI 分组')
    plt.ylabel('Y染色体浓度 (%)')
    plt.show()
else:
    print("\n数据框为空，无法进行可视化。请检查预处理步骤或原始数据。")